<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<meta http-equiv="X-UA-Compatible" content="IE=edge">
	<meta name="viewport" content="width=device-width, initial-scale=1.0">
	<title>Document</title>
    <style>
        .top {
            margin-bottom: 20px;
        }
        .bottom {
            margin-top: 40px;
        }
        .floattest {
            width: 500px;
            border: 1px solid orange;
        }
        .floattest .left {
            width: 200px;
            height: 200px;
            border: 1px solid red;
            float: left;
        }
        .floattest:after {
            content: "";
            display: block;
            height: 0;
            clear:both;
            visibility: hidden;
        }
        .floattest .right {
            width: 200px;
            height: 200px;
            border: 1px solid green;
            float: right;
        }
        .footer {
            width: 600px;
            height: 500px;
            border: 1px solid black;
        }  
        .father {
            position: relative;
            width: 400px;
            height: 400px;
            background-color: skyblue;
            margin: 100px auto;
        }
        .son {
            position: absolute;
            top: 0;
            left: 0;
            right: 0;
            bottom: 0;
            width: 200px;
            height: 200px;
            background-color: wheat;
            margin: auto;
        }
        .box {
				height: 300px;
				width: 100%;
				margin: 0 auto;
				background-color: red;
				position: relative;
				overflow: scroll;
				margin-top: 20px;
			}
            .box .abso{
				position: fixed;
				top: 0px;
				left:0;
				width: 110%;
				height: 50px;
				background-color: green;
			}
			.msg{
				width: 110%;
				height: 600px;
				background: red;
			}
            .hovercontent {
                width: 500px;
                height: 200px;
                background-color: gold;
            }
            .hovercontent :hover {
                display: block;
                width: 500px;
                height: 200px;
                background-color: aqua;
                animation: 0.2s ease alternate;
            }
    </style>
</head>
<body>
	<a href="mailto:sample@fly63.com?subject=test&cc=sample@hotmail.com&subject=主题&body=内容">send mail</a>
	<p>You can reach Michael at:</p>
		<ul>
		<li><a href="https://example.com">Website</a></li>
		<li><a href="mailto:m.bluth@example.com">Email</a></li>
		<li><a href="tel:+15237344561">Phone</a></li>
		</ul>
        <div class="top">
            top
        </div>
        <div class="bottom">
            bottom
        </div>
        <a href="#">111111111</a>
        <div class='floattest'>
            <div class='left'>
                left11111
                lorem
            </div>
            <div class='right'>
                right
            </div>
        </div>
        <div class='footer'>

        </div>
        <!-- 垂直居中 -->
        <div class='father'>
            <div class="son"></div>
        </div>
        <div class="box">
			<div class="abso">
				123123
			</div>
			<div class="msg">
				<p>123123sdasd</p>
				<p>123123sdasd</p>
				<p>123123sdasd</p>
				<p>123123sdasd</p>
				<p>123123sdasd</p>
				<p>123123sdasd</p>
				<p>123123sdasd</p>
				<p>123123sdasd</p>
			</div>
		</div>
        <div class='hovercontent'>
            aaaaaaaaaaaaaa
        </div>
</body>  


<script type='text/javascript'>
    console.log(11111)
    //构造函数应用
    function Grade(max, min, average) {
        this.max = max;
        this.min = min;
        this.average = average;
        this.sayhello = function() {
            console.log('sayhello')
        }
    }
    
    function Subject(subjectName,max, min, average) {
        Grade.call(this, max, min, average);
        this.subjectName = subjectName;
    }
    var math = new Subject('math', 99, 60, 80);
    console.log(math)
// console.log(new Grade())

// new 一个实例发生了什么
function Fun(name){
	this.name=name;
}
// Fun.prototype={
// 	constructor:Fun,
//     say(){
//     	console.log(this)
//         return 1 
//     }
// }
let a =new Fun('liudehua')
// console.log(a.say())
console.log(Fun.prototype)
console.log(a.__proto__.__proto__ === Fun.prototype.__proto__)
console.log(a.__proto__.__proto__, Fun.prototype.__proto__)

// this 指向问题
window.name = 'mish'
var obj = {
    name:'1',
    age:20,
    say: function() {
        console.log(this)
    }
}
// obj.call(window)
obj.say.call(window)


function fn(){
    this.user="LonJin";
    return function(){}
};
var b = new fn;
console.log(b.user);

//   模拟 new 
function recoverNew (){
    console.log(arguments)
    let obj = new Object()
    // let formalParameter1 = Array.from(arguments)[0]
    // console.log(formalParameter1)
    // console.log([].shift.call(arguments))
    let formalParameter = [].shift.call(arguments)
    obj.__proto__ = formalParameter.prototype
    let res = formalParameter.apply(obj, arguments)
    return  (res && typeof res === 'object') ? res : obj
}

function Person( name, age) {
    this.name = name 
    this.age = age
    // return function() {

    // }
    // return 
}

var person = new Person('xhua', 25)
// console.log(person.name)
let per = recoverNew(Person,'xhua',20)
console.log(per)

// 设计模式


// 观察者模式
// function Hunter(name, level) {
//     this.name = name 
//     this.level = level
//     this.list= []
// }

// Hunter.prototype.publish = function (money) {
//     console.log(this.level + '猎人' + this.name + '寻求帮助')
//     this.list.forEach(function(item, index){
//         item(money)
//     })
// }
// // 为什么订阅者可以获取到构造函数中的全部属性呢？
// Hunter.prototype.subscribe = function (targrt, fn) {
//     console.log(targrt)
//     console.log(this.level + '猎人' + this.name + '订阅了' + targrt.name)
//     targrt.list.push(fn)
// }

// let hunterMing = new Hunter('小明', '黄金')
// let hunterJin = new Hunter('小金', '白银')
// let hunterZhang = new Hunter('小张', '黄金')
// let hunterPeter = new Hunter('Peter', '青铜')

// hunterMing.subscribe(hunterPeter, function(money) {
//     console.log('小明表示：' + (money > 200 ? '' : '暂时很忙，不能') + '给予帮助')
// })
// hunterJin.subscribe(hunterPeter, function(){
//     console.log('小金表示：给予帮助')
// })
// hunterZhang.subscribe(hunterPeter, function(){
//     console.log('小张表示：给予帮助')
// })
// hunterPeter.publish(198)

// 发布者 订阅者模式

//定义一家猎人工会
//主要功能包括任务发布大厅(topics)，以及订阅任务(subscribe)，发布任务(publish)

let HunterUnion = {
    type:'hunt',
    topics: Object.create(null),
    subscribe: function(topic , fn ) {
        if (!this.topics[topic]) {
            this.topics[topic] = []
        }
        this.topics[topic].push(fn)
    },
    publish: function (topic, money) {
        if(!this.topics[topic]) {
            return;
            for ( let fn of this.topics[topic]) {
                fn(money)
            }
        }
    }
}

//定义一个猎人类
//包括姓名，级别
function Hunter(name, level){
    this.name = name
    this.level = level
}

Hunter.prototype.subscribe = function (topic, fn) {
    // console.log(this.level + '猎人' + this.name + '订阅了狩猎' + topic + '的任务')
    HunterUnion.subscribe(topic, fn)
}

Hunter.prototype.publish = function (topic, money) {
    // console.log(this.level + '猎人' + this.name + '发布了狩猎' + topic + '的任务')
    HunterUnion.publish(topic, money)
}

//猎人工会走来了几个猎人
let hunterMing = new Hunter('小明', '黄金')
let hunterJin = new Hunter('小金', '白银')
let hunterZhang = new Hunter('小张', '黄金')
let hunterPeter = new Hunter('Peter', '青铜')

//小明，小金，小张分别订阅了狩猎tiger的任务
hunterMing.subscribe('tiger', function(money){
    console.log(11111)
    console.log('小明表示：' + (money > 200 ? '' : '不') + '接取任务')
})
hunterJin.subscribe('tiger', function(money){
    console.log('小金表示：接取任务')
})
hunterZhang.subscribe('tiger', function(money){
    console.log('小张表示：接取任务')
})
//Peter订阅了狩猎sheep的任务
hunterPeter.subscribe('sheep', function(money){
    console.log('Peter表示：接取任务')
})

//Peter发布了狩猎tiger的任务
hunterPeter.publish('tiger', 198)
//猎人们发布(发布者)或订阅(观察者/订阅者)任务都是通过猎人工会(调度中心)关联起来的，他们没有直接的交流。


// console.log('start')
// Promise.resolve().then(() => {
//     console.log(0);
//     return Promise.resolve(4);
// }).then((res) => {
//     console.log(res)
// }).then(()=>{
//     console.log(10)
// })

// Promise.resolve().then(() => {
//     console.log(1);
// }).then(() => {
//     console.log(2);
// }).then(() => {
//     console.log(3);
// }).then(() => {
//     console.log(5);
// }).then(() =>{
//     console.log(6);
// })
// Promise.resolve().then(()=>{
//     console.log(7)
// })
// Promise.resolve().then(() => console.log('我也不知道'))
// console.log('end')

// function timeout(ms) {
//     return new Promise((resolve,reject)=> {
//         // setTimeout(resolve, ms, 'done')
//         console.log(10000)
//         setTimeout(()=>{
//             resolve('done')
//         },ms,'done')
//     });
// }

// timeout(100).then(value => {
//     console.log(value)
// })

// const p1 = new Promise(function (resolve, reject) {
//   setTimeout(() => reject(new Error('fail')), 3000)
// })

// const p2 = new Promise(function (resolve, reject) {
//   setTimeout(() => resolve(p1), 1000)
// })

// p2.then(result => console.log(result))
// .catch(error => console.log(error))


// Promise.resolve('foo')   // 等价于 
// new Promise(resolve => reslove('foo'))


let arr1 = [1,10]
let arr2 = [2,10]
console.log(arr1.concat(arr2,[4,5,6]))
console.log(arr2,arr1)


let objn = {
    name: 'xhua'
}
let obja = {
    age:20
}
console.log(Object.assign(obja,objn))
console.log(obja,objn)

let arrfind = [11,22,6,9,33,4,5,6,7,6,2]
let res= arrfind.find(v=>v === 9)
console.log(res)

// async await setTimeout

// async function async1() {
// 	console.log('async1 start'); //2
// 	await async2();
// 	console.log('asnyc1 end'); //6
// }
// async function async2() {
// 	console.log('async2'); //3
// }
// console.log('script start'); //  1
// setTimeout(() => {
// 	console.log('setTimeOut'); //8
// }, 0);

// async1();
// new Promise(function (reslove) {
// 	console.log('promise1'); //4
// 	reslove();
// }).then(function () {
// 	console.log('promise2'); //7
// })
// console.log('script end'); //5


// 1、执行console.log('script start')，输出script start；
// 2、执行setTimeout，是一个异步动作，放入宏任务异步队列中；
// 3、执行async1()，输出async1 start，继续向下执行；
// 4、执行async2()，输出async2，并返回了一个promise对象，await让出了线程，把返回的promise加入了微任务异步队列，所以async1()下面的代码也要等待上面完成后继续执行;
// 5、执行 new Promise，输出promise1，然后将resolve放入微任务异步队列；
// 6、执行console.log('script end')，输出script end；
// 7、到此同步的代码就都执行完成了，然后去微任务异步队列里去获取任务
// 8、接下来执行resolve（async2返回的promise返回的），输出了async1 end。
// 9、然后执行resolve（new Promise的），输出了promise2。
// 10、最后执行setTimeout，输出了settimeout。


//
// setTimeout(function(){
//     console.log('1')
// });
// new Promise(function(resolve){
//     console.log('2');
//     resolve();
// }).then(function(){
//     console.log('3')
// });
// console.log('4');

// new Promise(function(resolve){
//     console.log('5');
//     resolve();
// }).then(function(){
//     console.log('6')
// });
// setTimeout(function(){
//     console.log('7')
// });
// function bar(){
//     console.log('8')
//     foo()
//     console.log('bar end')
// }
// function foo(){
//     console.log('9')
// }
// console.log('10')
// bar()

// 2 4 5 10 8 9 3 6 1  7
</script>
</html>